home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-src / rd.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  19KB  |  479 lines

  1. /*  $VER: vbcc (rd.c) V0.4     */
  2. /*  verfuegbare Definitionen und constant propagation   */
  3.  
  4. #include "opt.h"
  5.  
  6. static char FILE_[]=__FILE__;
  7.  
  8. /*  fuer verfuegbare Definitionen   */
  9. unsigned int dcount;
  10. size_t dsize;
  11. struct IC **dlist;
  12. unsigned char **defs;       /*  gibt an, welche Definitionen, welche    */
  13.                             /*  Variablen definieren                    */
  14. /*  alle Definitionen, globaler oder Adr. fuer propagation etc.         */
  15. unsigned char *rd_globals,*rd_address,*rd_statics,*rd_drefs;
  16. /*  dasseble, aber hier nur die undefs  */
  17. unsigned char *rd_defs,*rd_tmp,*rd_parms;
  18.  
  19. /*  Bitvektor fuer geaenderte Variablen fuer ic_changes */
  20. unsigned char *rd_vars;
  21.  
  22. /*  rd_mode==0 => reaching definitions fuer constant-propagatione,      */
  23. /*  sonst fuer loop-invariant.                                          */
  24. int rd_mode;
  25.  
  26. int compare_const(union atyps *q1,union atyps *q2,int t)
  27. /*  vergleiht zwei Konstanten; -1, wenn q1<q2; 0, wenn q1==q1; 1 sonst  */
  28. {
  29.     zdouble d1,d2;zlong l1,l2;zulong u1,u2;zpointer p1,p2;
  30.     t&=NU;
  31.     eval_const(q1,t);p1=vpointer;d1=vdouble;l1=vlong;u1=vulong;
  32.     eval_const(q2,t);p2=vpointer;d2=vdouble;l2=vlong;u2=vulong;
  33.     if(t==POINTER) return(zulleq(u2,u1)?!zuleqto(u1,u2):-1);
  34.     if(t==DOUBLE||t==FLOAT) return(zdleq(d2,d1)?!zdeqto(d1,d2):-1);
  35.     if(t&UNSIGNED) return(zulleq(u2,u1)?!zuleqto(u1,u2):-1);
  36.     return(zlleq(l2,l1)?!zleqto(l1,l2):-1);
  37.     ierror(0);
  38. }
  39.  
  40. void print_rd(unsigned char *bitvector)
  41. /*  druckt Definitionen in einem Bitvektor */
  42. {
  43.     unsigned int i;
  44.     if(!bitvector) {printf("reaching definitions not available\n");return;}
  45.     for(i=1;i<=dcount;i++)
  46.         if(BTST(bitvector,i)) {printf("%3u:",i);pric2(stdout,dlist[i]);}
  47.     for(i=0;i<vcount-rcount;i++)
  48.         if(BTST(bitvector,i+dcount+1)) printf("%3u:\t\tundefined\t->%s\n",i+dcount+1,vilist[i]->identifier);
  49.     for(i=vcount-rcount;i<vcount;i++)
  50.         if(BTST(bitvector,i+dcount+1)) printf("%3u:\t\tundefined\t->(%s)\n",i+dcount+1,vilist[i]->identifier);
  51. }
  52.  
  53. void num_defs(void)
  54. /*  Numeriert alle Variablendefinitionen (nur elementare Typen noetig)  */
  55. /*  und erzeugt diverse Bitvektoren.                                    */
  56. {
  57.     int i=0;struct IC *p;
  58.     if(DEBUG&1024) printf("numerating definitions\n");
  59.     for(p=first_ic;p;p=p->next){
  60.         if(!(p->z.flags&VAR)&&p->code!=CALL){p->defindex=0;continue;}
  61. /*        if((p->z.v->vtyp->flags&NQ)>POINTER){p->defindex=0;continue;}*/
  62.         p->defindex=++i;
  63.     }
  64.     dcount=i;dsize=(dcount+CHAR_BIT+vcount)/CHAR_BIT;    /* +1, da bei 1 anfaengt */
  65.     if(DEBUG&1024) printf("%lu definitions, dsize=%lu\n",(unsigned long)dcount,(unsigned long)dsize);
  66.     /*  fuer jede Variable wird eine kuenstliche unbestimmte Def. erzeugt   */
  67.     /*  Feld erzeugen, dass zu jeder Variable alle Definitionen erhaelt    */
  68.     defs=mymalloc(sizeof(unsigned char *)*vcount);
  69.     for(i=0;i<vcount;i++){
  70.         defs[i]=mymalloc(dsize);
  71.         memset(defs[i],0,dsize);
  72.         BSET(defs[i],i+dcount+1);
  73.     }
  74.     dlist=mymalloc((dcount+1)*sizeof(struct IC *));
  75.     rd_globals=mymalloc(dsize);
  76.     memset(rd_globals,0,dsize);
  77.     rd_statics=mymalloc(dsize);
  78.     memset(rd_statics,0,dsize);
  79.     rd_address=mymalloc(dsize);
  80.     memset(rd_address,0,dsize);
  81.     rd_drefs=mymalloc(dsize);
  82.     memset(rd_drefs,0,dsize);
  83.  
  84.     rd_vars=mymalloc(vsize);
  85.  
  86.     for(p=first_ic;p;p=p->next){
  87.         if(p->defindex){
  88.             if(p->z.flags&VAR){
  89.                 i=p->z.v->index;
  90.                 if(p->z.flags&DREFOBJ) i+=vcount-rcount;
  91.                 BSET(defs[i],p->defindex);
  92.             }
  93.             dlist[p->defindex]=p;
  94.         }
  95.     }
  96.     if(DEBUG&2048){
  97.         for(i=1;i<=dcount;i++){ printf("Def%3d: ",i);pric2(stdout,dlist[i]);}
  98.         for(i=0;i<vcount;i++){
  99.             printf("Definitionen fuer <%s>:\n",vilist[i]->identifier);
  100.             print_rd(defs[i]);
  101.         }
  102.     }
  103.     for(i=0;i<vcount-rcount;i++){   /*  rd_globals berechnen    */
  104.         if(vilist[i]->vtyp->flags&CONST) continue;
  105.         if(vilist[i]->nesting==0||vilist[i]->storage_class==EXTERN) bvunite(rd_globals,defs[i],dsize);
  106.         if(vilist[i]->flags&USEDASADR) bvunite(rd_address,defs[i],dsize);
  107.         if(vilist[i]->storage_class==STATIC) bvunite(rd_statics,defs[i],dsize);
  108.         if(i<rcount){
  109.             bvunite(rd_address,defs[i+vcount-rcount],dsize);
  110.             bvunite(rd_globals,defs[i+vcount-rcount],dsize);
  111.             bvunite(rd_drefs,defs[i+vcount-rcount],dsize);
  112.         }
  113.     }
  114.     rd_parms=mymalloc(dsize);
  115.     memset(rd_parms,0,dsize);
  116.     for(i=0;i<vcount;i++){
  117.         struct Var *v=vilist[i];
  118.         if(i>=vcount-rcount||zl2l(v->offset)<0||(v->flags®PARM)||v->nesting==0||v->storage_class==EXTERN||v->storage_class==STATIC){
  119.             BSET(rd_parms,i+dcount+1);
  120.         }
  121.     }
  122. /*    if(DEBUG&1024){printf("rd_globals:\n");print_rd(rd_globals);}*/
  123. }
  124. int complete_def(struct IC *p)
  125. /*  Testet, ob eine Definition die Zielvariable komplett setzt oder nur */
  126. /*  teilweise.                                                          */
  127. {
  128.     struct Typ *t=p->z.v->vtyp;
  129.     zlong s1,s2;
  130.     if(p->z.flags&DREFOBJ) t=t->next;
  131.     if(!t) return(0);
  132.     s1=szof(t);
  133.     if(p->code==ASSIGN||p->code==GETRETURN) s2=p->q2.val.vlong;
  134.         else s2=sizetab[p->typf&NQ];
  135. /*    if(s1<s2) ierror(0);*/
  136.     if(zleqto(s1,s2)) return(1); else return(0);
  137. }
  138. void reaching_definitions(struct flowgraph *fg)
  139. /*  Berechnet die verfuegbaren Definitionen fuer jeden Block.   */
  140. {
  141.     struct flowgraph *g;struct IC *p;unsigned char *tmp;
  142.     int changed,pass,i,j;
  143.     /*  rd_gen und rd_kill fuer jeden Block berechnen   */
  144.     if(DEBUG&1024) printf("analysing reaching definitions\n");
  145.     tmp=mymalloc(dsize);
  146.     g=fg;
  147.     while(g){
  148.         g->rd_in=mymalloc(dsize);
  149.         memset(g->rd_in,0,dsize);
  150.         g->rd_out=mymalloc(dsize);
  151.         memset(g->rd_out,0,dsize);
  152.         g->rd_gen=mymalloc(dsize);
  153.         memset(g->rd_gen,0,dsize);
  154.         g->rd_kill=mymalloc(dsize);
  155.         memset(g->rd_kill,0,dsize);
  156.         p=g->end;
  157.         while(p){
  158.             if(p->defindex){
  159.                 int zi=-1;
  160.                 if(!BTST(g->rd_kill,p->defindex)) BSET(g->rd_gen,p->defindex);
  161.                 if(p->z.flags&VAR){
  162.                     if(!BTST(g->rd_kill,p->defindex)&&complete_def(p)){
  163.                         zi=p->z.v->index;
  164.                         if(p->z.flags&DREFOBJ) zi+=vcount-rcount;
  165.                         memcpy(tmp,defs[zi],dsize);
  166.                         bvdiff(tmp,g->rd_gen,dsize);
  167.                         bvunite(g->rd_kill,tmp,dsize);
  168.                     }
  169.                 }
  170.                 for(j=0;j<p->change_cnt;j++){
  171.                     i=p->change_list[j].v->index;
  172.                     if(p->change_list[j].flags&DREFOBJ) i+=vcount-rcount;
  173.                     if(i>=vcount) continue;
  174.                     if((i!=zi||(p->typf&NQ)>POINTER)&&!BTST(g->rd_kill,i+dcount+1)){
  175.                         BSET(g->rd_gen,i+dcount+1);
  176.                         if(i<rcount&&!BTST(g->rd_kill,dcount+1+i+vcount-rcount))
  177.                             BSET(g->rd_gen,i+vcount-rcount+dcount+1);
  178.                     }
  179.                 }
  180.             }
  181.  
  182.             if(p==g->start) break;
  183.             p=p->prev;
  184.         }
  185.         memcpy(g->rd_out,g->rd_gen,dsize);
  186.         g=g->normalout;
  187.     }
  188.  
  189.     /*  rd_in und rd_out fuer jeden Block berechnen */
  190.     /*  out(b)=gen(B) vorinitialisiert              */
  191.     if(DEBUG&1024) {printf("pass:");pass=0;}
  192.     do{
  193.         if(DEBUG&1024) {printf(" %d",++pass);fflush(stdout);}
  194.         changed=0;
  195.         g=fg;
  196.         while(g){
  197.             struct flowlist *lp;
  198.             /*  in(B)=U out(C) : C Vorgaenger von B */
  199.             if(g==fg) memcpy(g->rd_in,rd_parms,dsize);
  200.                 else  memset(g->rd_in,0,dsize);
  201.             lp=g->in;
  202.             while(lp){
  203.                 if(!lp->graph) ierror(0);
  204.                 if(lp->graph->branchout==g||!lp->graph->end||lp->graph->end->code!=BRA)
  205.                     bvunite(g->rd_in,lp->graph->rd_out,dsize);
  206.                 lp=lp->next;
  207.             }
  208.             /*  out(b)=gen(B) U (in(B)-kill(B)  */
  209.             memcpy(tmp,g->rd_in,dsize);
  210.             bvdiff(tmp,g->rd_kill,dsize);
  211.             bvunite(tmp,g->rd_gen,dsize);
  212.             if(!bvcmp(tmp,g->rd_out,dsize)){changed=1;memcpy(g->rd_out,tmp,dsize);}
  213.             g=g->normalout;
  214.         }
  215.     }while(changed);
  216.     if(DEBUG&1024) printf("\n");
  217.     free(tmp);
  218. }
  219. void calc(int c,int t,union atyps *q1,union atyps *q2,union atyps *z,struct IC *p)
  220. /*  berechnet z:=q1 op q2; mit Konstanten                           */
  221. {
  222.     zdouble d1,d2;zlong l1,l2;zulong u1,u2;
  223.     eval_const(q1,t);
  224.     d1=vdouble;l1=vlong;u1=vulong;
  225.     if(c!=MINUS&&c!=KOMPLEMENT){
  226.         eval_const(q2,t);
  227.         d2=vdouble;l2=vlong;u2=vulong;
  228.     }
  229.     if(c==ADD){ vdouble=zdadd(d1,d2);vlong=zladd(l1,l2);vulong=zuladd(u1,u2);}
  230.     if(c==SUB){ vdouble=zdsub(d1,d2);vlong=zlsub(l1,l2);vulong=zulsub(u1,u2);}
  231.     if(c==MULT){ vdouble=zdmult(d1,d2);vlong=zlmult(l1,l2);vulong=zulmult(u1,u2);}
  232.     if(c==DIV||c==MOD){
  233.         if(zdeqto(d2,d2zd(0.0))&&zleqto(l2,l2zl(0L))&&zuleqto(u2,ul2zul(0UL))){
  234.             err_ic=p;error(210);err_ic=0;
  235.             vlong=l2zl(0L);vulong=ul2zul(0L);vdouble=zl2zd(l1);
  236.         }else{
  237.             if(c==DIV){vdouble=zddiv(d1,d2);if(!zleqto(l2,l2zl(0L))) vlong=zldiv(l1,l2);if(!zuleqto(u2,ul2zul(0UL))) vulong=zuldiv(u1,u2);}
  238.              else     {if(!zleqto(l1,l2zl(0L))) vlong=zlmod(l1,l2);if(!zuleqto(u2,ul2zul(0UL))) vulong=zulmod(u1,u2);}
  239.         }
  240.     }
  241.     if(c==AND){ vlong=zland(l1,l2);vulong=zuland(u1,u2);}
  242.     if(c==OR){ vlong=zlor(l1,l2);vulong=zulor(u1,u2);}
  243.     if(c==XOR){ vlong=zlxor(l1,l2);vulong=zulxor(u1,u2);}
  244.     if(c==LSHIFT){ vlong=zllshift(l1,l2);vulong=zullshift(u1,u2);}
  245.     if(c==RSHIFT){ vlong=zlrshift(l1,l2);vulong=zulrshift(u1,u2);}
  246.     if(c==MINUS){ vdouble=zdsub(d2zd(0.0),d1);vlong=zlsub(l2zl(0L),l1);vulong=zulsub(ul2zul(0UL),u1);}
  247.     if(c==KOMPLEMENT){ vlong=zlkompl(l1);vulong=zulkompl(u1);}
  248.  
  249.     vint=zl2zi(vlong);vshort=zl2zs(vlong);vchar=zl2zc(vlong);
  250.     vuint=zul2zui(vulong);vushort=zul2zus(vulong);vuchar=zul2zuc(vulong);
  251.     vfloat=zd2zf(vdouble);
  252.     insert_const2(z,t);
  253. }
  254.  
  255. int fold(struct IC *p)
  256. /*  wertet konstante ICs aus    */
  257. {
  258.     int c;
  259.     if(!p) ierror(0);
  260.     c=p->code;
  261.     if(c==ADDI2P||c==SUBIFP||c==SUBPFP||c==ASSIGN||c==PUSH||c==SETRETURN) return(0);
  262.     if(DEBUG&1024) {printf("folding IC:\n");pric2(stdout,p);}
  263.     if(c==TEST||c==COMPARE){
  264.         union atyps val;int cc; /*  condition codes */
  265.         struct IC *bp;
  266.         if(c==TEST){
  267.             eval_const(&p->q1.val,p->typf);
  268.             if(zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))&&zdeqto(vdouble,d2zd(0.0))) cc=0; else cc=1;
  269.         } else cc=compare_const(&p->q1.val,&p->q2.val,p->typf);
  270.         bp=p->next;
  271.         if(bp->code>=BEQ&&bp->code<=BGT&&(!p->z.flags||p->z.v==bp->q1.v)){
  272.             if(DEBUG&1024) printf("(cc=%d; comparison eliminated)\n",cc);
  273.             if(have_alias){ free(p->use_list);free(p->change_list);}
  274.             remove_IC(p);
  275.             while(1){   /*  zugehoerigen Branch suchen  */
  276.                 if(!bp||bp->code==LABEL||bp->code==BRA) ierror(0);
  277.                 c=bp->code;
  278.                 if(c>=BEQ&&c<=BGT) break;
  279.                 bp=bp->next;
  280.             }
  281.             if((c==BEQ&&cc==0)||(c==BNE&&cc!=0)||(c==BLT&&cc<0)||(c==BGT&&cc>0)||(c==BLE&&cc<=0)||(c==BGE&&cc>=0)){
  282.                 if(DEBUG&1024){ printf("changed following branch to BRA:\n");pric2(stdout,bp);}
  283.                 bp->code=BRA;bp->q1.flags=0;
  284.             }else{
  285.                 if(DEBUG&1024){ printf("removed following branch:\n");pric2(stdout,bp);}
  286.                 if(have_alias){ free(bp->use_list);free(bp->change_list);}
  287.                 remove_IC(bp);
  288.             }
  289.             return(1);
  290.         }
  291.     }
  292.     if(c>=CONVCHAR&&c<=CONVULONG){
  293.         int t;
  294.         if(c==CONVCHAR) t=CHAR;
  295.         if(c==CONVUCHAR) t=UNSIGNED|CHAR;
  296.         if(c==CONVSHORT) t=SHORT;
  297.         if(c==CONVUSHORT) t=UNSIGNED|SHORT;
  298.         if(c==CONVINT) t=INT;
  299.         if(c==CONVUINT) t=UNSIGNED|INT;
  300.         if(c==CONVLONG) t=LONG;
  301.         if(c==CONVULONG) t=UNSIGNED|LONG;
  302.         if(c==CONVFLOAT) t=FLOAT;
  303.         if(c==CONVDOUBLE) t=DOUBLE;
  304.         if(c==CONVPOINTER) t=POINTER;
  305.         eval_const(&p->q1.val,t);
  306.         insert_const2(&p->q1.val,p->typf);
  307.     }else calc(c,p->typf,&p->q1.val,&p->q2.val,&p->q1.val,p);
  308.     p->q2.flags=0;
  309.     p->q2.val.vlong=sizetab[p->typf&NQ];
  310.     p->code=ASSIGN;
  311.     if(DEBUG&1024){printf("becomes\n");pric2(stdout,p);}
  312.     return(1);
  313. }
  314. int propagate(struct obj *o,int replace)
  315. /*  versucht, Objekte durch Konstanten zu ersetzen und erkennt manche   */
  316. /*  nicht initialisierten Variablen; ist replace==0, wird nicht ersetzt */
  317. {
  318.     unsigned int i,j,t;union atyps *val=0;
  319.     struct Var *v;struct IC *p;
  320.     if(!o||!o->v) ierror(0);
  321.     v=o->v;
  322.     i=v->index;
  323.     if(o->flags&DREFOBJ) i+=vcount-rcount;
  324.     if(DEBUG&2048){
  325.         printf("propagate <%s>\n",o->v->identifier);
  326.         if(o->flags&DREFOBJ) printf("(DREFOBJ)");
  327.         printf("\nall reaching definitions:\n");print_rd(rd_defs);
  328.         printf("definitions of object:\n");print_rd(defs[i]);
  329.     }
  330.     if(v->nesting==0||v->storage_class==STATIC||v->storage_class==EXTERN){
  331.     /*  Wenn moeglich bei statischen Variablen den Wert bei der         */
  332.     /*  Initialisierung ermitteln.                                      */
  333.         if(replace&&(v->vtyp->flags&NQ)<=DOUBLE&&((v->vtyp->flags&CONST)||(v->nesting>0&&!(v->flags&(USEDASADR|USEDASDEST))))){
  334.             /*  Variable hat noch den Wert der Initialisierung.         */
  335.             if(v->clist){
  336.                 /*  Der Wert der Initialisierung ist noch gespeichert.  */
  337.                 if(DEBUG&1024) printf("using static initializer\n");
  338.                 o->val=v->clist->val;
  339.                 o->flags=KONST;
  340.                 return(1);
  341.             }else{
  342.                 /*  Hier evtl. eine implizite 0 erkennen.               */
  343.             }
  344.         }
  345.     }
  346.     if(BTST(rd_defs,i+dcount+1)) return(0);
  347.     memcpy(rd_tmp,rd_defs,dsize);
  348.     bvintersect(rd_tmp,defs[i],dsize);
  349.     i=0;
  350.     for(j=1;j<=dcount;j++){
  351.         if(BTST(rd_tmp,j)){
  352.             p=dlist[j];
  353.             /*  Die Def. muss mit dem Objekt uebereinstimmen (koennte   */
  354.             /*  auch ein anderes Struktur- oder Arrayy-Element sein).   */
  355.             /*  Dann uebergehen, aber merken, dass eine Def. existiert, */
  356.             /*  um keine falsche "used before defined"-Meldung zu       */
  357.             /*  erzeugen.                                               */
  358.             if(compare_objs(&p->z,o,p->typf)){ i=1; continue;}
  359.             /*  Wenn die Def. kein einfacher Typ ist, muss sie von      */
  360.             /*  einer evtl. spaeteren Def. ueberschrieben worden sein,  */
  361.             /*  da oben schon auf undefined geprueft wurde.             */
  362.             if((p->typf&NQ)>POINTER){ i=1; continue; }
  363.             /*  Wenn es keine Zuweisung einer Konstanten ist, ist keine */
  364.             /*  Weitergabe von Konstanten moeglich.                     */
  365.             if(p->code!=ASSIGN) return(0);
  366.             if((p->q1.flags&(KONST|DREFOBJ))!=KONST) return(0);
  367.             if(val){
  368.                 /*  Wenn mehr als eine Konstante, muessen alle gleich sein  */
  369.                 /*  und den gleichen Typ haben.                             */
  370.                 if((p->typf&NU)!=t) return(0);
  371.                 if(compare_const(&p->q1.val,val,t)) return(0);
  372.             }else{
  373.                 val=&p->q1.val;t=p->typf&NU;
  374.             }
  375.         }
  376.     }
  377.     /*  kann Konstante einsetzen    */
  378.     if(val){
  379.         if(!replace) return(0);
  380.         if(DEBUG&1024){ printf("can <%s> replace by constant\n",o->v->identifier);}
  381.         o->val=*val;
  382.         o->flags=KONST;
  383.         return(1);
  384.     }
  385.     /*  gar keine Definition gefunden   */
  386.     if(!i&&!(v->flags&USEDBEFORE)){
  387.         error(171,v->identifier);v->flags|=USEDBEFORE;
  388.         if(!*v->identifier) {probj(stdout,o,0);prd(stdout,v->vtyp);printf("; offset=%ld\n",zl2l(v->offset));}
  389.     }
  390.     return(0);
  391.  
  392. }
  393. int constant_propagation(struct flowgraph *fg,int global)
  394. /*  sucht nach konstanten Ausdruecken und nicht definierten Variablen   */
  395. /*  wenn global!=0, dann werden reaching definitions benutzt und global */
  396. /*  optimiert, ansonsten nur innerhalb von basic blocks                 */
  397. {
  398.     struct IC *p;int changed=0,i;struct flowgraph *g;
  399.     if(DEBUG&1024){printf("trying constant propagation\n");}
  400.     rd_defs=mymalloc(dsize);
  401.     rd_tmp=mymalloc(dsize);
  402.     g=fg;
  403.     while(g){
  404.         if(global) memcpy(rd_defs,g->rd_in,dsize);
  405.             else   memset(rd_defs,~0,dsize);
  406.         p=g->start;
  407.         while(p){
  408. /*            if(DEBUG&1024){print_rd(rd_defs);pric2(stdout,p);}*/
  409.             if(p->code!=ADDRESS&&p->code!=NOP&&(p->typf&NQ)<=POINTER&&(p->code<LABEL||p->code>BRA)){
  410.                 int i;
  411.                 if((p->q1.flags&(VAR|VARADR))==VAR){
  412.                     i=p->q1.v->index;
  413.                     if(p->q1.flags&DREFOBJ) i+=vcount-rcount;
  414.                     changed|=propagate(&p->q1,1);
  415.                 }
  416.                 if((p->q2.flags&(VAR|VARADR))==VAR){
  417.                     i=p->q2.v->index;
  418.                     if(p->q2.flags&DREFOBJ) i+=vcount-rcount;
  419.                     changed|=propagate(&p->q2,1);
  420.                 }
  421.             }
  422.             /*  sollte eigentlich nichts bringen, ausser evtl. Meldung  */
  423.             /*  bei unitiialisierter Variablen                          */
  424.             if(((p->z.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ))){
  425.                 i=p->z.v->index+vcount-rcount;
  426.                 if(!BTST(rd_defs,i+dcount+1))
  427.                     changed|=propagate(&p->z,0);
  428.             }
  429.             rd_change(p);
  430.  
  431.             if(p==g->end) break;
  432.             p=p->next;
  433.         }
  434.         g=g->normalout;
  435.     }
  436.  
  437.     gchanged|=changed;
  438.     for(i=0;i<vcount;i++) free(defs[i]);
  439.     free(defs);
  440.     free(dlist);
  441.     free(rd_globals);
  442.     free(rd_statics);
  443.     free(rd_address);
  444.     free(rd_drefs);
  445.     free(rd_tmp);
  446.     free(rd_defs);
  447.     free(rd_parms);
  448.     free(rd_vars);
  449.     return(changed);
  450. }
  451. void rd_change(struct IC *p)
  452. /*  Fuehrt die Aenderungen in rd_defs durch, die bei IC p auftreten.    */
  453. /*  Benutzt eine ganze Reihe globaler Bitvektoren.                      */
  454. {
  455.     int i,j,zi=-1;
  456. /*    print_rd(rd_defs);*/
  457.     if(p->defindex){
  458.         if(p->z.flags&VAR){
  459.             zi=p->z.v->index;
  460.             if(p->z.flags&DREFOBJ) zi+=vcount-rcount;
  461.         }
  462.         for(j=0;j<p->change_cnt;j++){
  463.             i=p->change_list[j].v->index;
  464.             if(p->change_list[j].flags&DREFOBJ) i+=vcount-rcount;
  465.             if(i>=vcount) continue;
  466.             if(i!=zi||(p->typf&NQ)>POINTER){
  467.                 BSET(rd_defs,i+dcount+1);
  468.                 if(i<rcount) BSET(rd_defs,i+vcount-rcount+dcount+1);
  469.             }
  470.         }
  471.         if(zi>=0&&complete_def(p)){
  472.             bvdiff(rd_defs,defs[zi],dsize);
  473.         }
  474.         BSET(rd_defs,p->defindex);
  475.     }
  476. /*    pric2(stdout,p);*/
  477. }
  478.  
  479.